import 'package:english_words/english_words.dart';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:isolate';

/**
 * 创建日期：2022/3/15
 * @author Zhangzhenguo
 * @version 1.0
 * 类说明：flutter中的view
 * 在Android中，View是屏幕上显示的所有内容的基础， 按钮、工具栏、输入框等一切都是View。 在Flutter中，View相当于是Widget。
 * 然而，与View相比，Widget有一些不同之处。 首先，Widget仅支持一帧，并且在每一帧上，Flutter的框架都会创建一个Widget实例树
 * (译者语：相当于一次性绘制整个界面)。 相比之下，在Android上View绘制结束后，就不会重绘，直到调用invalidate时才会重绘。
 * 与Android的视图层次系统不同（在framework改变视图），而在Flutter中的widget是不可变的，这允许widget变得超级轻量。
 */
class UpdateWidget extends StatefulWidget {
  @override
  _UpdateWidgetState createState() => _UpdateWidgetState();
}

class _UpdateWidgetState extends State<UpdateWidget> {
  var showTitle = 'hello flutter';

  _setTitle() {
    setState(() {
      showTitle = '咯吱，被戳了一下';
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('如何更新view'),
      ),
      body: Center(child: Text(showTitle)),
      floatingActionButton: FloatingActionButton(
        onPressed: _setTitle,
        tooltip: '浮动按钮',
        child: Icon(Icons.add),
      ),
    );
  }
}

/**
 * xml布局去哪了
 */
class XmlLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('xml布局去哪了'),
      ),
      body: Center(
        child: MaterialButton(
          child: Text('xml 布局去哪了'),
          onPressed: () {},
          padding: EdgeInsets.only(left: 110, right: 10, top: 20),
          color: Colors.red,
        ),
      ),
    );
  }
}

/**
 * 如何在布局中增加或删除组件
 * 在Android中，您可以从父级控件调用addChild或removeChild以动态添加或删除View。
 * 在Flutter中，因为widget是不可变的，所以没有addChild。相反，您可以传入一个函数，
 * 该函数返回一个widget给父项，并通过布尔值控制该widget的创建。
 */

class WidgetAddOrDel extends StatefulWidget {
//  构造方法
  WidgetAddOrDel({Key key}) : super(key: key);

  @override
  _WidgetAddOrDelState createState() => new _WidgetAddOrDelState();
}

class _WidgetAddOrDelState extends State<WidgetAddOrDel> {
//  默认的标识
  bool toggle = true;
  String showTitle = '111';

  void _toggle() {
    setState(() {
      toggle = !toggle;
      print(toggle);
    });
  }

  _getToggleChild() {
    if (toggle) {
      showTitle = 'toggle one';
      print("toggle one");
      return new Text(showTitle);
    } else {
      showTitle = 'toggle two';
      print("toggle two");
      return new MaterialButton(onPressed: () {}, child: new Text(showTitle));
    }
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new Center(
        child: _getToggleChild(),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _toggle,
        tooltip: 'Update Text',
        child: new Icon(Icons.update),
      ),
    );
  }
}

/**
 * flutter使用动画对Widget进行处理
 * 在Flutter中，可以通过动画库给widget添加动画。
 * 在Android中，您可以通过XML创建动画或在视图上调用.animate()。在Flutter中，您可以将widget包装到Animation中。
 * 与Android相似，在Flutter中，您有一个AnimationController和一个Interpolator， 它是Animation类的扩展，
 * 例如CurvedAnimation。您将控制器和动画传递到AnimationWidget中，并告诉控制器启动动画。
 * 让我们来看看如何编写一个FadeTransition，当您按下时会淡入一个logo:
 */
class MyFadeTest extends StatefulWidget {
  MyFadeTest({Key key}) : super(key: key);
  String titile;

  @override
  _MyFadeTestState createState() => _MyFadeTestState();
}

class _MyFadeTestState extends State<MyFadeTest> with TickerProviderStateMixin {
  AnimationController controller;
  CurvedAnimation curve;

  @override
  void initState() {
    controller = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 2000));
    // parent 此动画应用曲线的动画。curve正向使用的曲线。
    curve = new CurvedAnimation(parent: controller, curve: Curves.bounceIn);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('flutter使用动画对widget进行处理'),
      ),
      body: Center(
        child: Container(
          child: FadeTransition(
            opacity: curve,
            child: new FlutterLogo(
              size: 100,
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        tooltip: 'Fade',
        child: Icon(Icons.brush),
        onPressed: () {
          controller.forward();
        },
      ),
    );
  }
}

/**
 * Flutter 如何使用Canvas draw/paint   画布  绘制  画笔
 * Flutter有两个类可以帮助您绘制画布，CustomPaint和CustomPainter，它们实现您的算法以绘制到画布。
 * 在这个人气较高的的StackOverFlow答案中，您可以看到签名painter是如何实现的。
 * https://stackoverflow.com/questions/46241071/create-signature-area-for-mobile-app-in-dart-flutter
 */
class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);

  final List<Offset> points;

  void paint(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 5.0;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null)
        canvas.drawLine(points[i], points[i + 1], paint);
    }
  }

  bool shouldRepaint(SignaturePainter other) => other.points != points;
}

class Signature extends StatefulWidget {
  SignatureState createState() => new SignatureState();
}

class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];

  Widget build(BuildContext context) {
    return new GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox referenceBox = context.findRenderObject();
          Offset localPosition =
              referenceBox.globalToLocal(details.globalPosition);
          _points = new List.from(_points)..add(localPosition);
        });
      },
      onPanEnd: (DragEndDetails details) => _points.add(null),
      child: new CustomPaint(painter: new SignaturePainter(_points)),
    );
  }
}

class DemoApp extends StatelessWidget {
  Widget build(BuildContext context) => new Scaffold(body: new Signature());
}

void main() => runApp(new MaterialApp(home: new DemoApp()));

/**
 * 在flutter中如何自定义Widget
 */

class CustomButton extends StatelessWidget {
  final String lable;
  final IconData icon;

  CustomButton(this.lable, this.icon);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      children: [Text(lable), Icon(icon)],
    );
  }
}

/**
 * 列表关注及详情
 */
class SfWidget extends StatefulWidget {
  @override
  SfWidgetState createState() => new SfWidgetState();
}

class SfWidgetState extends State<SfWidget> {
//  存储显示的列表单词
  final _suggest = <WordPair>[];

//  列表字体显示样式
  final _biggerFont = const TextStyle(fontSize: 18);

//  存储收藏标记
  final _saved = new Set<WordPair>();

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        appBar: AppBar(
          title: Text('welcome to flutter'),
          actions: [
            new IconButton(onPressed: _pushSaved, icon: Icon(Icons.list))
          ],
        ),
        body: ListView.builder(
            padding: EdgeInsets.all(16),
            itemBuilder: (context, i) {
              // 如果是则添加分割线
              if (i.isOdd) return Divider();
              final index = i ~/ 2;
              if (index >= _suggest.length) {
                // 随机生成不同的单词  ：generateWordpairs.take(数量);
                _suggest.addAll(generateWordPairs().take(10));
              }
              print("dd" + _suggest.length.toString());
              return _buildRow(_suggest[index]);
            }));
  }

  Widget _buildRow(WordPair pair) {
    // 存储不收藏的
    final _alredySaved = _saved.contains(pair);
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: Icon(_alredySaved ? Icons.favorite : Icons.favorite_border,
          color: _alredySaved ? Colors.red : null),
      onTap: () {
        setState(() {
          if (_alredySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }

  /**
   * 路由跳转至详情页
   */
  void _pushSaved() {
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      final tiles = _saved.map((pair) => ListTile(
            title: Text(pair.asPascalCase, style: _biggerFont),
          ));
      final divided =
          ListTile.divideTiles(tiles: tiles, context: context).toList();
      print(divided);
      return Scaffold(
          appBar: AppBar(
            title: Text('details flutter page'),
          ),
          body: ListView(
            children: divided,
          ));
    }));
  }
}

/**
 * flutter中的异步UI
 */
class ASyncUI extends StatefulWidget {
  ASyncUI(Key key) : super(key: key);

  @override
  ASyncUIState createState() => ASyncUIState();
}

class ASyncUIState extends State<ASyncUI> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    loadData();
  }

  showLoadingDialog() {
    if (widgets.length == 0) {
      return true;
    }

    return false;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getListView();
    }
  }

  getProgressDialog() {
    return new Center(child: new CircularProgressIndicator());
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Sample App"),
        ),
        body: getBody());
  }

  ListView getListView() => new ListView.builder(
      itemCount: widgets.length,
      itemBuilder: (BuildContext context, int position) {
        return getRow(position);
      });

  Widget getRow(int i) {
    return new Padding(
        padding: new EdgeInsets.all(10.0),
        child: new Text("Row ${widgets[i]["title"]}"));
  }

  loadData() async {
    ReceivePort receivePort = new ReceivePort();
    await Isolate.spawn(dataLoader, receivePort.sendPort);

    // The 'echo' isolate sends it's SendPort as the first message
    SendPort sendPort = await receivePort.first;

    List msg = await sendReceive(
        sendPort, "https://jsonplaceholder.typicode.com/posts");

    setState(() {
      widgets = msg;
    });
  }

// the entry point for the isolate
  static dataLoader(SendPort sendPort) async {
    // Open the ReceivePort for incoming messages.
    ReceivePort port = new ReceivePort();

    // Notify any other isolates what port this isolate listens to.
    sendPort.send(port.sendPort);

    await for (var msg in port) {
      String data = msg[0];
      SendPort replyTo = msg[1];

      String dataURL = data;
      // http.Response response = await http.get(dataURL);
      // Lots of JSON to parse
      // replyTo.send(JSON.decode(response.body));
    }
  }

  Future sendReceive(SendPort port, msg) {
    ReceivePort response = new ReceivePort();
    port.send([msg, response.sendPort]);
    return response.first;
  }
}

//全局静态变量
class Strings {
  static String welcomeMessage = '1111';
}

class LifecycleWatcher extends StatefulWidget {
  @override
  LifecycleWatcherState createState() => LifecycleWatcherState();
}

class LifecycleWatcherState extends State<LifecycleWatcher>
    with WidgetsBindingObserver {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }
}

/**
 * 行布局
 */
class RelatLayoutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('row one'),
        Text('row two'),
        Text('row three'),
        Text('row four'),
        Text('row five'),
      ],
    );
  }
}

/**
 * 线布局
 */
class LinearLayoutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('row one'),
        Text('row two'),
        Text('row three'),
        Text('row four'),
        Text('row five'),
        GestureDetector(
          child: Text("星河大海"),
          onTap: () {
            print("1111");
          },
        )
      ],
    );
  }
}

/**
 * 动态更新listview的adapter
 */
class UpAdapter extends StatefulWidget {
  @override
  UpAdapterState createState() => UpAdapterState();
}

class UpAdapterState extends State<UpAdapter> {
  List<Widget> items = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    for (int i = 0; i < 100; i++) {
      items.add(_getRow(i));
      print(items[i]);
    }
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        appBar: AppBar(
          title: Text("动态更新adapter"),
        ),
        body: ListView.builder(
          itemBuilder: (BuildContext context, int position) {
            return _getRow(position);
          },
          itemCount: items.length,
        ));
  }

  _getRow(int item) {
    return GestureDetector(
      onTap: () {
        setState(() {
          // 将老数据重新set到新集合中
          items = List.from(items);
          //添加新数据到数据源中
          items.add(_getRow(items.length + 1));
        });
      },
      child: Padding(
        padding: EdgeInsets.all(10),
        child: Text("row $item"),
      ),
    );
  }
}
